#include "RTClock.h"
#include "gd32e23x_i2c.h"
#include "gd32e230c_bsp.h"
#include <string.h>
#include "pos_param.h"

//#define RTC_CLOCK_SOURCE_IRC40K
#define RTC_CLOCK_SOURCE_LXTAL
uint16_t prescaler_a, prescaler_s;
// PCF8563 02h: ? ? ? ? ??(??) ? ?
tClock c;

uint8_t ToDec(uint8_t bcd)   //bcd ? Dec
{
	uint8_t a,b,hex;
	a=bcd /16;
	b=bcd %16;
	hex =a*10+b;
	return hex;
}
static uint8_t ToBcd(uint8_t hex)   //Dec ? bcd 
{
	uint8_t a,b,bcd;
	a=hex /10;
		b=hex %10;
	bcd =(a<<4)|b;
		return bcd;
}
//GD32E2_RTCGetClock
tClock GetClock (void)
{
    rtc_parameter_struct rd_rtc;

    rtc_current_time_get(&rd_rtc);

    c.Second = rd_rtc.rtc_second;
    c.Minute = rd_rtc.rtc_minute;
    c.Hour = rd_rtc.rtc_hour ;

    c.Year = rd_rtc.rtc_year;
    c.Month = rd_rtc.rtc_month;
    c.Day = rd_rtc.rtc_date;
    return c;
}

void rtc_pre_config(void)
{
    /* enable access to RTC registers in backup domain */
    rcu_periph_clock_enable(RCU_PMU); // ??RTC???????
    pmu_backup_write_enable();

#if defined (RTC_CLOCK_SOURCE_IRC40K)
    /* enable the IRC40K oscillator */
    rcu_osci_on ( RCU_IRC40K );
    /* wait till IRC40K is ready */
    rcu_osci_stab_wait ( RCU_IRC40K );
    /* select the RTC clock source */
    rcu_rtc_clock_config ( RCU_RTCSRC_IRC40K );

    prescaler_s = 0x18F;
    prescaler_a = 0x63;
#elif defined (RTC_CLOCK_SOURCE_LXTAL)
    /* enable the IRC40K oscillator */
    rcu_osci_on(RCU_LXTAL);
    /* wait till IRC40K is ready */
    rcu_osci_stab_wait(RCU_LXTAL);
    /* select the RTC clock source */
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);

    prescaler_s = 0xFF;
    prescaler_a = 0x7F;
#else
#error RTC clock source should be defined.
#endif /* RTC_CLOCK_SOURCE_IRC40K */

    rcu_periph_clock_enable(RCU_RTC);
    rtc_register_sync_wait();

    CheckBKP_RTC();
}

//????RTC
void SetClock (tClock *c)
{
    rtc_parameter_struct rtc_initpara_struct = {
        .rtc_am_pm = RTC_AM,
        .rtc_display_format = RTC_24HOUR,
        .rtc_factor_asyn = prescaler_a,
        .rtc_factor_syn = prescaler_s,
        .rtc_second = c->Second,
        .rtc_minute = c->Minute,
        .rtc_hour = c->Hour,
        .rtc_year = (uint8_t)(c->Year % 0x100),
        .rtc_month = c->Month,
        .rtc_date = c->Day
    };
    
    pmu_backup_write_enable();
    rtc_init(&rtc_initpara_struct);
}


void CheckBKP_RTC(void)
{
    /* check if RTC has aready been configured */
    if (BKP_VALUE != RTC_BKP0)
    {
        GetClock();
        RTC_BKP0 = BKP_VALUE;

        PosParam.FreeUseMode = 0; 
        PosParam.DayLimitFlag = 0; 

        PosParam.SaveParam();
    }
}



